home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-03 / qbnws303.zip / TEXTFONT.ZIP / FONTDEMO.BAS < prev    next >
BASIC Source File  |  1992-09-15  |  33KB  |  1,077 lines

  1. DEFINT A-Z
  2.  
  3.  
  4. '========================================================================
  5. '
  6. '   FontDemo.Bas        (by Rob Smetana for QBNews, 9/92)
  7. '                       (In case you have questions:  (415) 863-0530)
  8. '
  9. '   You MUST run this loading either Fonts7.QLB (QBX) or
  10. '   Fonts45.QLB (QB 4.x).  This demo needs screen font files
  11. '   contained in those Quick Libraries.  We also need the
  12. '   InterruptX routines.
  13. '
  14. '   If you use QBX/BC 7:        qbx fontdemo /L fonts7
  15. '     If you use QB 4.x:        qb  fontdemo /L fonts45
  16. '
  17. '   We also included Fonts.Lib -- with the Tiny, Script and Roman fonts.
  18. '   You can use it with either QB or PDS, once you've added it to your
  19. '   own LIB or QLB files.  For example:
  20. '
  21. '   PDS:  Link /q/seg:512  MyLib.Lib Fonts.Lib, SomeQLB, nul, QBXQLB;
  22. '   QB:   Link /q/seg:512  MyLib.Lib Fonts.Lib, SomeQLB, nul, BQLB45;
  23. '
  24. '
  25. '========================================================================
  26. '                    ---  NOTE USERS of QB 4.x  ---
  27. '========================================================================
  28. '
  29. ' BEFORE you run this, move to SUB LoadFontFile and COMMENT OUT the line:
  30. '
  31. '                       Registers.ES = SSEG(a$)
  32. '
  33. '    If you don't do this, you'll get an "Array Not Defined" error.
  34. '
  35. '========================================================================
  36.  
  37. TYPE RegTypeX                           ' TYPE required by InterruptX
  38.      AX    AS INTEGER
  39.      BX    AS INTEGER
  40.      CX    AS INTEGER
  41.      DX    AS INTEGER
  42.      BP    AS INTEGER
  43.      SI    AS INTEGER
  44.      DI    AS INTEGER
  45.      Flags AS INTEGER
  46.      DS    AS INTEGER
  47.      ES    AS INTEGER
  48. END TYPE
  49.  
  50. DIM SHARED Registers AS RegTypeX        ' For Call InterruptX ...
  51.  
  52. DECLARE SUB InterruptX (Interrupt, InRegs AS RegTypeX, OutRegs AS RegTypeX)
  53. DECLARE SUB LoadFontFile (FontFile$, CharWidth%, FirstChar%, NumberChars%, UsingFarStrings%)
  54. DECLARE SUB RestoreDefault (WhichMonitor)
  55. DECLARE SUB ToggleSize (Which%)
  56. DECLARE SUB Sideways.Logo ()
  57. DECLARE SUB PauseTicks (Ticks%)
  58. DECLARE SUB Demonstrate.Symbols ()
  59. DECLARE SUB Demonstrate.Loading.Fonts ()
  60. DECLARE SUB Demo.CALLing.Fonts ()
  61. DECLARE SUB Demo.text.AND.graphics ()
  62.  
  63. DECLARE FUNCTION QB.Monitor% (ScrnRows%)
  64. DECLARE FUNCTION PressKey$ (Row%, Col%, Action%)
  65.  
  66. PressAKey$ = " Press any key to continue... "      '...used in several places
  67.  
  68.  
  69. '====== "SCREEN , 0" helps ensure QB/QBX restore a normal font when you
  70. '       return to the environment.  This comes in v-e-r-y handy when
  71. '       you start experimenting and render your screen unreadable!
  72. '       Note:  That's NOT Screen 0!
  73.  
  74.     SCREEN , 0
  75.  
  76.     COLOR 11, 1
  77.     CLS
  78.     WIDTH , 25                          '...DON'T change this!  43- or 50-
  79.                                         '   line modes will truncate char-
  80.                                         '   acters.  (OK Rick, try 43 or 50
  81.                                         '   and see what I mean.)
  82.  
  83. '=========================================================================
  84. '... Determine monitor type.  We "should" only proceed if EGA/VGA detected.
  85. '=========================================================================
  86.  
  87.     WhichMonitor = QB.Monitor(LastRow)  '...note:  returns 2 values
  88.                                         '   we won't use LastRow, but
  89.                                         '   you might find it helpful
  90.     SELECT CASE WhichMonitor
  91.         CASE 3, 4                       '...EGA- or VGA-compatible
  92.         CASE ELSE
  93.              PRINT
  94.              PRINT "This demo should be run on an EGA or VGA monitor.  You CAN proceed,"
  95.              PRINT "but you'll miss most of the good parts, and some things won't work."
  96.              PRINT "Press Ctrl-Break now if you'd like to stop.";
  97.              a$ = INPUT$(1)
  98.     END SELECT
  99.  
  100.  
  101. '========================================================================
  102. '... Display one of our logos
  103. '========================================================================
  104.  
  105.     Sideways.Logo
  106.  
  107.     COLOR 11, 1: CLS
  108.  
  109.     RestoreDefault WhichMonitor
  110.  
  111. '========================================================================
  112. '... demonstrate how easy it is to change text fonts by CALLing FontName
  113. '========================================================================
  114.  
  115.     Demo.CALLing.Fonts
  116.  
  117.  
  118.     '... By NOT restoring the default font, you'll see how you can
  119.     '    switch fonts, then remap some characters in the NEW font.
  120.     '    UN-REM the next line to re-set the font BEFORE the next demo.
  121.  
  122.     'RestoreDefault WhichMonitor
  123.  
  124. '========================================================================
  125. '... demonstrate different types of symbols one can create
  126. '========================================================================
  127.  
  128.     Demonstrate.Symbols
  129.  
  130.     RestoreDefault WhichMonitor
  131.  
  132. '========================================================================
  133. '... demonstrate how to load fonts FROM DISK
  134. '========================================================================
  135.  
  136.     Demonstrate.Loading.Fonts
  137.  
  138.     RestoreDefault WhichMonitor
  139.  
  140.  
  141. '========================================================================
  142.  
  143.     CLS
  144.     PRINT
  145.     PRINT "  Finally, you can switch among the 2-3 fonts you already have.  Here we'll"
  146.     PRINT "  switch to the small 8x8 font.  Both EGA and VGA monitors also have an"
  147.     PRINT "  8x14 font.  VGA monitors also have an 8x16 font."
  148.  
  149. '========================================================================
  150.  
  151.     LOCATE 6, 1
  152.     FOR x = 1 TO 10
  153.         PRINT " We'll now switch to the small 8x8 font available on both EGA and VGA monitors."
  154.     NEXT
  155.  
  156.     CALL ToggleSize(2)              'Option MUST be: 1 (8x14) 2 (8x8) or 4 (8x16 -- VGA only)
  157.  
  158.     a$ = PressKey$(22, 25, 0)
  159.  
  160.  
  161.     CLS
  162.  
  163.     RestoreDefault WhichMonitor
  164.  
  165. '========================================================================
  166. '... Display an ASM/OBJ screen created with P-Screen, then end.
  167. '========================================================================
  168.  
  169.     CLS
  170.  
  171.     CALL ThatsAll
  172.  
  173.     LOCATE 20, 1
  174.     PRINT "  Be SURE to run Adv-Demo.Exe.  It demonstrates:"
  175.     PRINT "   1.  How you can use the same fonts in both text AND graphics modes."
  176.     PRINT "   2.  How VERY SIMPLE font changes can change the SHAPE of the MOUSE CURSOR."
  177.     PRINT "       Just re-map a character, then:  "
  178.     PRINT "            CALL SetTextCursor (Foreground, Background, WhichCharacter)!"
  179.  
  180.     a$ = PressKey$(25, 25, 0)
  181.  
  182. '========================================================================
  183.  
  184. END
  185.  
  186.  
  187. LogoBox:       '...used in our sideways logo demo
  188.  
  189. DATA "┌───────────────────────────────────────┐"
  190. DATA "│                                       │"
  191. DATA "│   ┌───────────────────────────────┐   │"
  192. DATA "│   │                               │   │"
  193. DATA "│   │                               │   │"
  194. DATA "│   │                               │   │"
  195. DATA "│   │                               │   │"
  196. DATA "│   │                               │   │"
  197. DATA "│   │                               │   │"
  198. DATA "│   │                               │   │"
  199. DATA "│   │                               │   │"
  200. DATA "│   │                               │   │"
  201. DATA "│   │                               │   │"
  202. DATA "│   │                               │   │"
  203. DATA "│   │                               │   │"
  204. DATA "│   └───────────────────────────────┘   │"
  205. DATA "│                                       │"
  206. DATA "└───────────────────────────────────────┘"
  207.  
  208. '
  209. SUB Demo.CALLing.Fonts
  210.  
  211.     SHARED PressAKey$
  212.  
  213. '========================================================================
  214.  
  215. PRINT TAB(34); "Text Font Demo":
  216.  
  217. PRINT : PRINT
  218. PRINT "      Next we'll show how easy it is to CALL [font name] to change the "
  219. PRINT "      appearance of screens by simply switching fonts.  "
  220. PRINT
  221. PRINT "      NOTE:  We'll be CALLing fonts created by Font2ASM -- which we included"
  222. PRINT "      here for your use.  Just assemble the ASM files, LINK the fonts to your"
  223. PRINT "      programs, then just CALL .... to use them."
  224.  
  225. LOCATE 24, 47: PRINT PressAKey$; "  "; : a$ = INPUT$(1)
  226.  
  227. '========================================================================
  228.  
  229.  
  230. LOCATE 3, 1
  231. GOSUB DisplayDemo                           '===== 1st, display some text
  232. LOCATE 24, 5: PRINT "This is your normal text font.";
  233. a$ = INPUT$(1)
  234.  
  235.  
  236.                                             '===== 2nd, switch fonts
  237.  
  238. LOCATE 24, 5: PRINT "CALL TINY -- our Tiny Font.   ";
  239.     CALL Tiny
  240.     Action = 0                              '===== Display scrolling "Press ..."
  241.                                             'Action = 0 ==> Take control
  242.                                             'and wait for key.
  243.     a$ = PressKey$(24, 47, Action)
  244.  
  245.  
  246. LOCATE 24, 5: PRINT "CALL ROMAN14 -- our Roman Font.";
  247.     CALL Roman14: a$ = PressKey$(24, 47, 0)
  248.  
  249.  
  250. LOCATE 24, 5: PRINT "CALL SCRIPT -- our Script Font.";
  251.     CALL Script: a$ = PressKey$(24, 47, 0)
  252.  
  253.  
  254. EXIT SUB
  255.  
  256.  
  257. '========================
  258. DisplayDemo:
  259. '========================
  260. d$ = " "
  261. PRINT d$; " ┌─░░░░░░░░░▒▒▒▒▒▒▒▒▒▒▒▓▓▓▓▓▓▓▓▓▓▓ FONT DEMO ▓▓▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒░░░░░░░░─┐"
  262. PRINT d$; "░│                                                                          │"
  263. PRINT d$; "░│                                                                          │"
  264. PRINT d$; "░│ We are NOT displaying different screens!  We'll display this once. Then, │"
  265. PRINT d$; "░│ as we load different fonts, the appearance changes.  Fonts remain in     │"
  266. PRINT d$; "░│ effect until you select another, or until a program changes screen modes.│"
  267. PRINT d$; "░│                                                                          │"
  268. PRINT d$; "░│ Notice that we will NOT replace all characters -- just ASCII 33 to 127.  │"
  269. PRINT d$; "░│ Why?  To keep fonts small, and because we really don't want to change    │"
  270. PRINT d$; "░│ the line-draw and shading characters.                                    │"
  271. PRINT d$; "░│                                                                          │"
  272. PRINT d$; "░│   +------+-----+  Now is the time for all good men to come to the aid... │"
  273. PRINT d$; "░│   |      |     |  ABCDEFGHIJKLMNOPQRSTUVWXYZ  abcdefghijklmnopqrstuvwxyz │"
  274. PRINT d$; "░│   +------+-----+                                                         │"
  275. PRINT d$; "░│                                                                          │"
  276. PRINT d$; "░│ 1234567890 -=!@#$%^&*()_+[] {};'<>?,./\|~`ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥ │"
  277. PRINT d$; "░│                                                                          │"
  278. PRINT d$; "░│           ₧ƒáíóúñѪº¿⌐¬½¼¡«»        αßΓπΣσµτΦΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■       │"
  279. PRINT d$; "░└──────────────────────────────────────────────────────────────────────────┘"
  280. PRINT d$; "░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░";
  281.  
  282. RETURN
  283.  
  284.  
  285. END SUB
  286.  
  287. '
  288. SUB Demonstrate.Loading.Fonts
  289.  
  290.     SHARED PressAKey$
  291.  
  292. '========================================================================
  293.  
  294. CLS
  295. PRINT
  296. PRINT "   Next, we'll load some fonts from disk.  To do this we need to know"
  297. PRINT "   whether you're using QB or QBX."
  298. PRINT
  299. PRINT "   NOTE, the font files MUST exist on the current drive/directory."
  300. PRINT "   We WON'T check.  So ensure ULine.14 and Italics.14 are here."
  301.  
  302. '========================================================================
  303.  
  304.  
  305. '====== Sub LoadFontFile must know whether Near or Far strings are being used.
  306.  
  307. UsingFarStrings = 0                         ' assume we're using QB 4.x
  308.  
  309. DO
  310.  
  311.     LOCATE 12, 1, 1
  312.     PRINT "   Please answer this CORRECTLY!  Press 7 or 4 ONLY."
  313.     PRINT
  314.     PRINT "   Are you using QB 4.x or QBX/BC7 with Far Strings?  Press (4) or (7) --> ";
  315.  
  316.     BEEP
  317.  
  318.     a$ = INPUT$(1)
  319.  
  320.  
  321. LOOP UNTIL a$ = "7" OR a$ = "4"
  322.  
  323. IF a$ = "7" THEN UsingFarStrings = -1       ' we need this in LoadFontFile
  324.  
  325.  
  326. GOSUB Demonstrate.Underlined.Text
  327.  
  328. GOSUB Demonstrate.Italic.Text
  329.  
  330.  
  331. EXIT SUB
  332.  
  333. '==============================================================
  334. Demonstrate.Underlined.Text:
  335. '==============================================================
  336.  
  337. FontFile$ = "ULine.14"
  338.  
  339. a$ = "An example of UNDERLINED text."
  340.  
  341. GOSUB SetUp.For.Examples
  342.  
  343. a$ = "UNDERLINED, all you have to do is print   HIGH ASCII characters (in this example)."
  344.  
  345. GOSUB PrintAsHighAscii
  346.  
  347. GOSUB TranslatePressAKey
  348.  
  349. RETURN
  350. '==============================================================
  351. Demonstrate.Italic.Text:
  352. '==============================================================
  353.  
  354. FontFile$ = "Italics.14"
  355.  
  356. a$ = "An example of ITALIC text . . ."
  357.  
  358. GOSUB SetUp.For.Examples
  359.  
  360. a$ = "in ITALICS, all you have to do is print   HIGH ASCII characters (in this example)."
  361.  
  362. GOSUB PrintAsHighAscii
  363.  
  364. GOSUB TranslatePressAKey
  365.  
  366. RETURN
  367.  
  368. '==============================================================
  369. SetUp.For.Examples:
  370. '==============================================================
  371.  
  372. '===== Both of our sample font files have 64 characters (the basics).
  373. '      Each character's bit map is 14 bytes, and we'll load 'em high
  374. '      (ie., we'll replace ASCII characters 128 +).
  375.  
  376. NumberChars = 64: CharWidth = 14: FirstChar = 128
  377.  
  378. CALL LoadFontFile(FontFile$, CharWidth, FirstChar, NumberChars, UsingFarStrings)
  379.  
  380. CLS
  381. PRINT TAB(24);
  382. GOSUB PrintAsHighAscii                      '...print our title
  383. COLOR 15, 1
  384. PRINT : PRINT : PRINT : PRINT
  385. PRINT " You can print NORMAL text."
  386. PRINT : PRINT
  387. PRINT " And you can 'mix-and-match' characters -- by re-mapping only some characters"
  388. PRINT " (eg., 1-31 or 128+), and then ....  well, you'll see."
  389. PRINT : PRINT
  390.  
  391. PRINT " For example, if you want text printed ";
  392. COLOR 7, 1
  393. RETURN
  394.  
  395.  
  396. '==============================================================
  397. PrintAsHighAscii:   '...We replaced high ASCII characters with
  398. '                   '   Italic or Underline characters.  To
  399.                     '   use these, we simply add 64 to the
  400.                     '   ASCII value of each character -- since
  401.                     '   we load our fonts 64 characters higher
  402.                     '   than normal.
  403. '==============================================================
  404.  
  405. FOR x = 1 TO LEN(a$)
  406.  
  407.     Which = ASC(MID$(a$, x))
  408.     IF Which > 64 THEN Which = Which + 64    '... "A" and above
  409.     PRINT CHR$(Which);
  410.  
  411. NEXT
  412.  
  413. RETURN
  414.  
  415. '==============================================================
  416. TranslatePressAKey:
  417. '==============================================================
  418.  
  419.     LOCATE 22, 25
  420.  
  421.     a$ = PressAKey$
  422.  
  423.     GOSUB PrintAsHighAscii
  424.  
  425.     a$ = INPUT$(1)
  426.  
  427. RETURN
  428.  
  429. END SUB
  430.  
  431. '
  432. SUB Demonstrate.Symbols
  433.  
  434. CLS
  435.  
  436.     CALL Symbols                '... load our Symbol font
  437.  
  438.     GOSUB DisplaySymbols        '... show examples of symbols you can create
  439.  
  440.     GOSUB LargeSymbols          '... and even larger symbols
  441.  
  442.     GOSUB ShowHand              '... pointer to words
  443.  
  444.     CLS : COLOR 14
  445.  
  446. EXIT SUB
  447.  
  448.  
  449. '====================================================
  450. DisplaySymbols:     '... illustrate several symbols
  451. '====================================================
  452.  
  453.  
  454.     Char = 14: b$ = "How about a Copyright Symbol!"
  455.         GOSUB DoSymbol
  456.  
  457.     Char = 15: b$ = "Or a Registered Trademark Symbol!"
  458.         GOSUB DoSymbol
  459.  
  460.     Char = 16: b$ = "Or a TEXT-MODE Pointing Hand Cursor!"
  461.         GOSUB DoSymbol
  462.  
  463. RETURN
  464.  
  465. '====================================================
  466. DoSymbol:
  467. '====================================================
  468.  
  469.     CLS
  470.     COLOR 14
  471.     LOCATE , 40 - (LEN(b$) \ 2) + 1
  472.     PRINT b$
  473.  
  474.     PRINT
  475.     COLOR 10
  476.  
  477.     b$ = " " + CHR$(Char)
  478.     FOR x = 1 TO 800: PRINT b$; : NEXT
  479.  
  480.     CALL PauseTicks(60)
  481.  
  482. RETURN
  483.  
  484. '====================================================
  485. LargeSymbols:   '... demo how one might create LARGE symbols
  486. '====================================================
  487.  
  488. '...Display our large P~F Logo.  We'll create 3 characters out of 7.
  489.  
  490.     COLOR 14
  491.     CLS : PRINT
  492.  
  493.     FirstLine$ = CHR$(17) + CHR$(18) + CHR$(19) + CHR$(20) + CHR$(21)
  494.     Line2$ = CHR$(22) + "  " + CHR$(23)
  495.  
  496.     PRINT TAB(14); "You can print LARGE characters or symbols in TEXT mode!"
  497.     PRINT : PRINT : PRINT
  498.  
  499.     FOR x = 1 TO 6
  500.         PRINT "      "; FirstLine$; "    "; FirstLine$; "    "; FirstLine$; "    "; FirstLine$; "    "; FirstLine$; "    "; FirstLine$; "    "; FirstLine$; "    "; FirstLine$
  501.         PRINT "      "; Line2$; "     "; Line2$; "     "; Line2$; "     "; Line2$; "     "; Line2$; "     "; Line2$; "     "; Line2$; "     "; Line2$
  502.         PRINT
  503.     NEXT
  504.  
  505.     CALL PauseTicks(60)
  506.  
  507. RETURN
  508.  
  509. '====================================================
  510. ShowHand:   '... use hand symbol to track words
  511. '====================================================
  512.  
  513.     CLS
  514.  
  515.     b$ = "Now please follow along, follow along, follow along ..... "
  516.  
  517.  
  518.     Row = 10
  519.     Pointer$ = CHR$(16)             '...our pointing hand
  520.  
  521.     FOR DoTwice = 1 TO 2
  522.         Start = 1
  523.         LOCATE Row, 10
  524.         TotalWordLength = 0
  525.  
  526.         DO UNTIL Start > LEN(b$)
  527.  
  528.             WordLength = INSTR(Start, b$, " ") - Start + 1
  529.  
  530.             '... find & print each word
  531.             Word$ = MID$(b$, Start, WordLength)
  532.  
  533.             LOCATE Row, 10 + TotalWordLength + 1
  534.  
  535.             COLOR 14
  536.             PRINT Word$;
  537.  
  538.             TotalWordLength = TotalWordLength + WordLength
  539.  
  540.             '... locate beneath the word and print our Pointing Hand
  541.             LOCATE Row + 1, (POS(0) - WordLength \ 2) - 1
  542.             COLOR 2
  543.             PRINT Pointer$;
  544.  
  545.             CALL PauseTicks(8)
  546.  
  547.             Start = Start + WordLength
  548.  
  549.         LOOP
  550.         Row = Row + 4
  551.  
  552.         CALL PauseTicks(25)
  553.  
  554.     NEXT
  555.  
  556.     CALL PauseTicks(60)
  557.  
  558.  
  559. RETURN
  560.  
  561. END SUB
  562.  
  563. '
  564. SUB LoadFontFile (FontFile$, CharWidth, FirstChar, NumberChars, UsingFarStrings)
  565.  
  566.  
  567.     '====== Replace the EGA or VGA font by loading an on-disk font file.
  568.  
  569.     '       "Registers" is a SHARED TYPE  (DIM SHARED Registers as RegTypeX).
  570.  
  571.  
  572.     FontFile = FREEFILE
  573.  
  574.     OPEN FontFile$ FOR BINARY AS #FontFile
  575.  
  576.  
  577.     a$ = SPACE$(LOF(FontFile))        ' To load the entire font in one gulp
  578.  
  579.     GET #FontFile, , a$               ' Read the font
  580.     CLOSE #FontFile
  581.  
  582.  
  583.     '====== 1st, describe our font:  # of Characters, width, where to begin
  584.  
  585.     Registers.CX = NumberChars        ' Number of chars in our font file
  586.  
  587.     Registers.BX = CharWidth * 256 + Which   ' BH = # of bytes in each character's
  588.                                       ' bit map (eg., 8, 14, 16, etc.).
  589.                                       ' Since it must go in BH, we multiply
  590.                                       ' by 256.
  591.  
  592.                                       ' BL (block to load) will be 0
  593.  
  594.     Registers.DX = FirstChar          ' DX = Offset to begin loading.  Example:
  595.                                       ' -To replace Chr$(33) +, FirstChar = 33
  596.                                       ' -To replace Chr$(224) +, FirstChar = 224
  597.  
  598.                                       '  NOTE:  You can begin loading ANYWHERE.
  599.                                       '  The only caveat is that FirstChar +
  600.                                       '  NumberChars CANNOT exceed 255.
  601.  
  602.     '====== just checking ...
  603.  
  604.     IF FirstChar + NumberChars > 255 THEN
  605.        CLS : PRINT "Error in parameters.  Too many characters, or starting too high."
  606.        END
  607.     END IF
  608.  
  609.  
  610.     '====== 2nd, locate our font:  its Segment and Address
  611.  
  612.     IF UsingFarStrings THEN           ' IF you're using QB 4.x, COMMENT OUT
  613.                                       ' the next line.
  614.  
  615.        Registers.ES = SSEG(a$)        ' Segment if using QBX/BC7's FAR strings
  616.  
  617.     ELSE
  618.  
  619.        Registers.ES = VARSEG(a$)      ' Segment if using QB or BC7's NEAR strings
  620.  
  621.     END IF
  622.  
  623.     Registers.BP = SADD(a$)           ' The address of our string.
  624.  
  625.  
  626.     '====== We're all set.  Now LOAD the font.
  627.  
  628.     Registers.AX = &H1100             ' Use Function 11h, Service 0 (Load)
  629.                                       ' of Interrupt 10.
  630.                                       ' AH = 11h - The function we want
  631.                                       ' AL =   0 - Load user font
  632.  
  633.     InterruptX &H10, Registers, Registers   ' Invoke BIOS service 10 with CALL Interrupt
  634.  
  635.  
  636.     '====== Now SET (or SELECT) it.
  637.  
  638.     Registers.AX = &H1103             ' Use Function 11h, Service 3 (Set)
  639.                                       ' of Interrupt 10.
  640.  
  641.                                       ' AH = 11h - The function we want
  642.                                       ' AL =   3 - Set (Select) our font
  643.  
  644.     Registers.BX = 0                  ' BL = Which block to load (parallels
  645.                                       ' what we did above when loading it)
  646.  
  647.     InterruptX &H10, Registers, Registers    ' Invoke BIOS service 10h
  648.  
  649. END SUB
  650.  
  651. '
  652. SUB PauseTicks (Ticks)
  653.  
  654.  
  655. '...Routine to pause for ?? ticks.  From Larry Stone's PrintROM.Bas.
  656.  
  657.     DEF SEG = 0
  658.  
  659.     DO WHILE TestTick% < Ticks      'Pause for X ticks of the clock
  660.  
  661.         LastTick% = Tick%           'Compare w/ Tick to see if clock changed
  662.         Tick% = PEEK(&H46C)         'Get a tick from the clock.
  663.  
  664.         IF LastTick% <> Tick% THEN TestTick% = TestTick% + 1
  665.  
  666.     LOOP
  667.  
  668.  
  669. '... The version below gives a little more precision, but
  670. '    works very differently on fast/slow PCs.
  671.  
  672. '    DEF SEG = 0                    '...we'll look in (Peek) low memory
  673. '
  674. '    DO UNTIL TestTick > Ticks
  675. '
  676. '        LastTick = GetTick
  677. '
  678. '        GetTick = PEEK(&H46C)      'Get a tick from the clock.
  679. '
  680. '        IF LastTick < GetTick + 1 THEN TestTick = TestTick + 1
  681. '
  682. '    LOOP
  683.  
  684.  
  685.  
  686.  
  687.     '...back to normal in either case
  688.     DEF SEG
  689.  
  690.  
  691.  
  692.  
  693. END SUB
  694.  
  695. '
  696. FUNCTION PressKey$ (Row, Col, Action)
  697.  
  698.     SHARED PressAKey$           '...share this to eliminate need to re-assign
  699.  
  700.     STATIC Offset               '...preserve between calls to use this in
  701.                                 '   "polled" mode
  702.  
  703.     '...Display a scrolling "Press any key to continue . . ."
  704.     '   You MUST set the colors before invoking this!
  705.  
  706.     '...We separated this so we could call it from several places.
  707.     '   This should also make it easier for you to use it elsewhere.
  708.  
  709.  
  710.     '...ACTION determines whether this takes over, or just scrolls the
  711.     '   message once and bails out (ie., works in "polled mode").
  712.     '
  713.     '   Action = 0        Take control, re-initialize Offset to 1 (start
  714.     '                     display at beginning), wait for a keypress,
  715.     '                     return the key pressed in PressKey$.
  716.     '
  717.     '            1        Re-set Offset to 1 (start display at beginning),
  718.     '                     print PressAKey$ and exit.
  719.     '
  720.     '            2        Scoll PressAKey$ and exit.
  721.  
  722.  
  723.     '... Should we reset to begin printing at the beginning?
  724.  
  725.     SELECT CASE Action
  726.        
  727.         CASE 0, 1: Offset = 0
  728.  
  729.     END SELECT
  730.  
  731.     Length = LEN(PressAKey$)
  732.  
  733.     DO
  734.  
  735.  
  736.         Offset = Offset + 1
  737.         IF Offset > LEN(PressAKey$) THEN Offset = 1
  738.  
  739.         '...display our prompt
  740.  
  741.         LOCATE Row, Col
  742.  
  743.         PRINT RIGHT$(PressAKey$, Length - Offset + 1); LEFT$(PressAKey$, Offset - 1);
  744.     
  745.         '... If we were called in "polled mode," exit.
  746.  
  747.         SELECT CASE Action
  748.             CASE 1, 2: EXIT FUNCTION
  749.  
  750.         END SELECT
  751.  
  752.  
  753.         '... don't use TIMER (and it's FP)
  754.  
  755.         '... PauseTicks has 2 versions
  756.         CALL PauseTicks(3)
  757.  
  758.          'CALL PauseTicks(500)
  759.  
  760.  
  761.         a$ = INKEY$
  762.  
  763.  
  764.     LOOP UNTIL LEN(a$)
  765.  
  766.     '...return key pressed
  767.     PressKey$ = a$
  768.  
  769. END FUNCTION
  770.  
  771. FUNCTION QB.Monitor (ScrnRows) STATIC
  772.  
  773.     '...Registers is a SHARED TYPE  (DIM SHARED Registers as RegTypeX)
  774.  
  775. '...Returns 2 Values:  1) the type of monitor being used      (QB.Monitor)
  776. '                      2) the current number of screen lines  (ScrnRows)
  777. '
  778. '   Usage:
  779. '
  780. '           ScrnSegment = &HB800                '...assume color (we don't
  781. '                                               '   use this, but you might
  782. '                                               '   need it)
  783. '
  784. '           SELECT CASE QB.Monitor(ScrnRows)    '...note:  returns 2 values
  785. '               Case 1: Print "Mono";
  786. '                       ScrnSegment = &HB000    '...in case you need it
  787. '               Case 2: Print "CGA";
  788. '               Case 3: Print "EGA";
  789. '               Case 4: Print "VGA";
  790. '           END SELECT
  791. '
  792. '           Print " monitor detected, which currently has this many rows: ";ScrnRows
  793.  
  794.                                             
  795.     ScrnRows = 25                           'assume 25 rows
  796.  
  797.  
  798.     DEF SEG = 0
  799.  
  800.     IF PEEK(&H463) = &HB4 THEN              'Is it monochrome?
  801.  
  802.         QB.Monitor = 1                      'Yes, and we're outta here.
  803.  
  804.     ELSE                                    'It's Color (CGA, EGA or VGA)?
  805.  
  806.         '...If we got here, it's color.  2 CALLs
  807.         '   will tell us if it's CGA, EGA or VGA.
  808.  
  809.         Registers.AX = &H1200               'Alternate Select service
  810.                                             'This is a mixed bag of services
  811.  
  812.         Registers.BX = &H10                 'We'll use "Return EGA info"
  813.  
  814.         CALL InterruptX(&H10, Registers, Registers)
  815.  
  816.         '...If BL = 10h (16), it's CGA
  817.  
  818.         IF (Registers.BX AND &HFF) = &H10 THEN
  819.  
  820.            QB.Monitor = 2                   'CGA
  821.  
  822.         ELSE
  823.  
  824.            '...if we're here, it's EGA or VGA -- but which?   Here,
  825.            '   we gotta know.
  826.  
  827.            QB.Monitor = 3                   'Assume EGA
  828.  
  829.  
  830.            ScrnRows = PEEK(&H484) + 1       'Get # of rows on screen.
  831.                                             'Adjust to 1-based.
  832.  
  833.             '... OK, it's either EGA or VGA.  But which?  Use Function
  834.             '    1Ah to test for VGA --- since 1Ah is NOT supported on
  835.             '    earlier adapters.  If AL (not AH) is 1Ah (26) AFTER
  836.             '    this call, a VGA-compatible adapter is present.
  837.  
  838.  
  839.             Registers.AX = &H1A00           'Display Combination Code  (the DCC)
  840.  
  841.             '...QB/QBX
  842.             CALL InterruptX(&H10, Registers, Registers)
  843.  
  844.  
  845.             IF Registers.AX MOD 256 = &H1A THEN
  846.  
  847.                 QB.Monitor = 4               'It's VGA
  848.  
  849.             END IF
  850.  
  851.             '...For the sake of completeness ....
  852.  
  853.             '   On return from this call, BH holds a code indicating
  854.             '   the **combination** of adapter and monitor -- the
  855.             '   "Display Combination Code" or DCC.
  856.             '
  857.             '   If you need this info, here are possible DCC values: : :
  858.             '
  859.             '   BH  =  &H0  ---  "No display"
  860.             '          &H1  ---  "IBM monochrome adapter AND display"
  861.             '          &H2  ---  "IBM CGA adapter AND color display"
  862.             '          &H3  ---  "This is reserved.  Don't know!"
  863.             '          &H4  ---  "IBM EGA with a color display"
  864.             '          &H5  ---  "IBM EGA, mono display"
  865.             '          &H6  ---  "IBM PGA, color display"
  866.             '          &H7  ---  "VGA, analog mono display"
  867.             '          &H8  ---  "VGA, analog color display"
  868.             '          &H9  ---  "This is reserved.  Don't know!"
  869.             '          &HA  ---  "MCGA, digital color display"
  870.             '          &HB  ---  "MCGA, analog mono display"
  871.             '          &HC  ---  "MCGA, analog color display"
  872.             '          &HFF ---  "Don't know!  Unknown monitor type."
  873.  
  874.         END IF
  875.  
  876.     END IF
  877.  
  878. DEF SEG
  879.  
  880.  
  881. END FUNCTION
  882.  
  883. '
  884. SUB RestoreDefault (WhichMonitor)
  885.  
  886.     '==== Restore the default font (16 or 14 for VGA/EGA respectively).
  887.  
  888.     SELECT CASE WhichMonitor
  889.  
  890.         CASE 4                          ' VGA or MCGA
  891.  
  892.             font = 4                    ' 8x16 Font
  893.  
  894.         CASE ELSE                       ' Assume EGA or an error in selecting
  895.  
  896.             font = 1                    ' 8x14 Font
  897.  
  898.     END SELECT
  899.  
  900.  
  901.     CALL ToggleSize(font)
  902.  
  903. END SUB
  904.  
  905. '
  906. SUB Sideways.Logo
  907.  
  908.     SHARED PressAKey$       '...in case you want to use it here
  909.  
  910.  
  911. '...Display "Pro~Formance" (our company name) in several different
  912. '   ways (sideways, upside down, etc.).
  913.  
  914.  
  915.     CLS
  916.  
  917.  
  918.     '...assign our strings
  919.  
  920.     Top$ = CHR$(255) + "  P R O ~ F O R M A N C E "     '255 is actually our
  921.                                                         'Copyright/TM symbol
  922.     Bottom$ = "  "
  923.  
  924.  
  925.     '... When we "CALL PFLogo" below, we'll re-map Chr$(219) - Chr$(255)
  926.     '    with our special font.
  927.     '
  928.     '    So we need strings using those characters.  Each of these spells
  929.     '    "PRO~FORMANCE."  "Yeah, right" I can hear you mumble.  You'll see!
  930.  
  931.     FOR x = 219 TO 230
  932.         RightSide$ = RightSide$ + CHR$(x)
  933.         LeftSide$ = LeftSide$ + CHR$(x + 24)
  934.         '...do the next one backwards
  935.         Bottom$ = Bottom$ + CHR$(241 - x + 220) + " "
  936.     NEXT
  937.  
  938.     Bottom$ = Bottom$ + " "
  939.     RightSide$ = RightSide$ + " "
  940.     LeftSide$ = LeftSide$ + " "
  941.  
  942.  
  943.     '...Load our logo font, remapping Chr$(219) through Chr$(255).
  944.     '   How do you know it's these characters being remapped?  Because
  945.     '   that's the way I set up the CALL for this font (created using
  946.     '   Font2Asm.
  947.  
  948.     CALL PFLogo
  949.  
  950.  
  951.     TopRow = 4
  952.  
  953.     '...1st, print everything statically
  954.  
  955.     LOCATE 2, 27, 0: PRINT Top$
  956.     LOCATE 23, 27: PRINT Bottom$;
  957.     LOCATE 25, 19: PRINT "... Remember, this is ALL in TEXT mode! ...";
  958.  
  959.     LeftCol = 12
  960.     RightSide = LeftCol + 53
  961.     SideOffset = LEN(LeftSide$)
  962.     GOSUB DoSides
  963.  
  964.     '...reset for everything else
  965.     LeftCol = 20
  966.     RightSide = LeftCol + 38
  967.  
  968.     '...display our box
  969.  
  970.     RESTORE LogoBox
  971.  
  972.     LOCATE TopRow
  973.     FOR x = 1 TO 18     '... print our 12-line box
  974.  
  975.         READ a$: LOCATE , LeftCol: PRINT a$
  976.  
  977.     NEXT
  978.  
  979.  
  980.     '...NOTE:  Commented-out lines will roll these in the opposite direction.
  981.  
  982.     Length = LEN(Top$)
  983.  
  984.     DO
  985.  
  986.  
  987.        Offset = Offset + 1
  988.        IF Offset > Length THEN Offset = 1
  989.  
  990.        '...Print the top line
  991.  
  992.        LOCATE TopRow + 1, LeftCol + 6
  993.        PRINT " "; RIGHT$(Top$, Length - Offset + 1); " "; LEFT$(Top$, Offset - 1); " ";
  994.          'PRINT " "; MID$(Top$, (Length - Offset + 1)); " "; LEFT$(Top$, (Length - Offset + 1)); " ";
  995.     
  996.        '...and our prompt  (Action = 2 means invoke PressKey$ in "polled" mode)
  997.  
  998.        COLOR 15, 1
  999.        a$ = PressKey$(TopRow + 8, LeftCol + 6, 2)
  1000.        COLOR 15, 4
  1001.     
  1002.        '...and the bottom
  1003.        LOCATE TopRow + 16, LeftCol + 5
  1004.        PRINT " "; MID$(Bottom$, (Length - Offset + 1)); " "; LEFT$(Bottom$, (Length - Offset + 1)); " ";
  1005.          'PRINT " "; MID$(Bottom$, Offset); " "; LEFT$(Bottom$, Offset - 1); " ";
  1006.     
  1007.        '...and now the sides
  1008.        GOSUB DoSides
  1009.     
  1010.        '... don't use TIMER (and it's FP)
  1011.  
  1012.        '... PauseTicks has 2 versions
  1013.        CALL PauseTicks(3)
  1014.         'CALL PauseTicks(500)
  1015.  
  1016.  
  1017.     LOOP UNTIL LEN(INKEY$)
  1018.  
  1019.  
  1020. EXIT SUB
  1021.  
  1022. '=======================================
  1023. DoSides:    '...do the sides of our box
  1024. '=======================================
  1025.  
  1026.     '...NOTE:  Commented-out lines will roll these in the opposite direction
  1027.  
  1028.     FOR x = 1 TO 12     '...12 characters in "Pro~Formance"
  1029.  
  1030.         SideOffset = SideOffset - 1
  1031.         IF SideOffset < 1 THEN SideOffset = LEN(LeftSide$)
  1032.  
  1033.         'SideOffset = SideOffset + 1
  1034.         'IF SideOffset > LEN(LeftSide$) OR SideOffset < 1 THEN SideOffset = 1
  1035.  
  1036.         LOCATE TopRow + x + 2, LeftCol + 2
  1037.         'LOCATE TopRow + 15 - x, LeftCol + 2
  1038.  
  1039.         PRINT MID$(LeftSide$, SideOffset, 1);
  1040.  
  1041.         LOCATE TopRow + 15 - x, RightSide
  1042.         'LOCATE TopRow + x + 2, RightSide
  1043.  
  1044.         PRINT MID$(RightSide$, SideOffset, 1);
  1045.  
  1046.         CALL PauseTicks(1)
  1047.            'CALL PauseTicks(200)
  1048.  
  1049.     NEXT
  1050.  
  1051. RETURN
  1052.  
  1053. END SUB
  1054.  
  1055. '
  1056. SUB ToggleSize (Which)    '... "Which" MUST be:   1 (8x14) 2 (8x8) 4 (8x16)
  1057.  
  1058.  
  1059.     '...Registers is a SHARED TYPE  (DIM SHARED Registers as RegTypeX)
  1060.  
  1061.     '====== Switch among the 2-3 resident fonts (or restore the default).
  1062.  
  1063.  
  1064.     Registers.AX = &H1100 + Which     ' Use Function 11h, Service 0 (Load).
  1065.                                       '
  1066.                                       ' AH = 11h - The function we want
  1067.                                       ' AL = Which: 1 (8x14) 2 (8x8) 4 (8x16)
  1068.  
  1069.     Registers.BX = 0
  1070.  
  1071.  
  1072.     InterruptX &H10, Registers, Registers   ' Invoke BIOS service 10h
  1073.  
  1074.  
  1075. END SUB
  1076.  
  1077.